#include "FrameBufferPick.h"

mini_engine::FrameBufferPick::FrameBufferPick()
{
}

void mini_engine::FrameBufferPick::pick()
{
    uint32_t buffer_size = SwapChain::getSwapChain()->swapChainExtent.width * SwapChain::getSwapChain()->swapChainExtent.height * 4;

    VkDeviceMemory vk_device_memory;
    VkBuffer vk_buffer;
    VkBufferCreateInfo buffer_create_info{};
    buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    buffer_create_info.size = buffer_size;
    buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    if (vkCreateBuffer(LogicalDevice::logicalDevice, &buffer_create_info, nullptr, &vk_buffer) != VK_SUCCESS)
    {
    }

    VkMemoryRequirements vk_memory_requirements{};
    vkGetBufferMemoryRequirements(LogicalDevice::logicalDevice, vk_buffer, &vk_memory_requirements);

    uint32_t memory_type_index;
    VkPhysicalDeviceMemoryProperties physical_device_memory_properties;
    vkGetPhysicalDeviceMemoryProperties(PhysicalDevice::physicalDevice, &physical_device_memory_properties);
    for (uint32_t i = 0; i < physical_device_memory_properties.memoryTypeCount; i++)
    {
        if (vk_memory_requirements.memoryTypeBits & (1 << i) &&
            (physical_device_memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
        {
            memory_type_index = i;
        }
        else
        {
            memory_type_index = 0;
        }
    }

    VkMemoryAllocateInfo buffer_memory_allocate_info{};
    buffer_memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    buffer_memory_allocate_info.allocationSize = buffer_create_info.size;
    buffer_memory_allocate_info.memoryTypeIndex = memory_type_index;
    if (vkAllocateMemory(LogicalDevice::logicalDevice, &buffer_memory_allocate_info, nullptr, &vk_device_memory) != VK_SUCCESS)
    {
    }

    // VkCommandBufferAllocateInfo allocInfo{};
    // allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
    // allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    // allocInfo.commandPool = mini_engine::Command::commandPool;
    // allocInfo.commandBufferCount = 1;

    // VkCommandBuffer command_buffer;
    // vkAllocateCommandBuffers(mini_engine::LogicalDevice::logicalDevice, &allocInfo, &command_buffer);

    // VkCommandBufferBeginInfo beginInfo{};
    // beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
    // beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;

    // vkBeginCommandBuffer(command_buffer, &beginInfo);

    // vkCmdCopyBufferToImage(command_buffer, );

    uint32_t *data = nullptr;
    VkResult res = vkMapMemory(LogicalDevice::logicalDevice, vk_device_memory, 0, buffer_size, 0, (void **)&data);
    uint32_t element_count = buffer_size / sizeof(uint32_t);
    std::cout << data[240000] << endl;
    vkUnmapMemory(LogicalDevice::logicalDevice, vk_device_memory);
    vkDestroyBuffer(LogicalDevice::logicalDevice, vk_buffer, nullptr);
    vkFreeMemory(LogicalDevice::logicalDevice, vk_device_memory, nullptr);
}

mini_engine::FrameBufferPick::~FrameBufferPick()
{
}
